package ace.module.common.core.impl.api.impl;

import ace.cmp.core.model.R;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.DtoManager;
import ace.cmp.sdk.api.SdkApi;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * .
 * @author Caspar
 *
 */
public abstract class SdkApiImpl<EntityT, IdT, EntityDtoT, ManagerT extends DtoManager<EntityT, IdT, EntityDtoT>>
    implements SdkApi<EntityDtoT, IdT> {

  @Getter
  @Autowired
  private ManagerT manager;

  @Override
  public R<IdT> save(EntityDtoT input) {
    IdT id = this.getManager().saveDto(input, true);
    return R.ok(id);
  }

  @Override
  public R<IdT> saveNotNullField(EntityDtoT input) {
    IdT id = this.getManager().saveDto(input, false);
    return R.ok(id);
  }

  @Override
  public R<IdT> add(EntityDtoT input) {
    IdT id = this.getManager().addDto(input, true);
    return R.ok(id);
  }

  @Override
  public R<IdT> addNotNullField(EntityDtoT input) {
    IdT id = this.getManager().addDto(input, false);
    return R.ok(id);
  }

  @Override
  public R<IdT> modify(EntityDtoT input) {
    IdT id = this.getManager().modifyDto(input, true);
    return R.ok(id);
  }

  @Override
  public R<IdT> modifyNotNullField(EntityDtoT input) {
    IdT id = this.getManager().modifyDto(input, false);
    return R.ok(id);
  }

  @Override
  public R<Boolean> remove(List<IdT> input) {
    Boolean result = this.getManager().remove(input);
    return R.ok(result);
  }

  @Override
  public R<Boolean> removeLogic(List<IdT> input) {
    Boolean result = this.getManager().removeLogic(input);
    return R.ok(result);
  }

  @Override
  public R<EntityDtoT> getById(IdT id) {
    EntityDtoT result = this.getManager().getDtoById(id);
    return R.ok(result);
  }

  @Override
  public R<List<EntityDtoT>> getListByIdIn(@Valid @NotNull @NotEmpty IdT[] ids) {
    List<EntityDtoT> result = this.getManager().getDtoListByIdIn(new ArrayList<>(List.of(ids)));
    return R.ok(result);
  }

  @Override
  public R<Map<IdT, EntityDtoT>> getMapByIdIn(@Valid @NotNull @NotEmpty IdT[] ids) {
    Map<IdT, EntityDtoT> result = this.getManager().getDtoMapByIdIn(new ArrayList<>(List.of(ids)));
    return R.ok(result);
  }
}
